package org.study.async;

import java.util.concurrent.*;

/**
 * @author Administrator
 */
public class CompletableFutureTest02 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        completableFutureTest01();
        completableFutureTest02();
        completableFutureTest03();
        completableFutureTest04();
        completableFutureTest05();
        completableFutureTest06();
        completableFutureTest07();
    }

    /**
     * CompletableFuture 变换结果
     */
    public static void completableFutureTest01() {
        String result = CompletableFuture.supplyAsync(() -> "Hello ")
                .thenApplyAsync(v -> v + "world")
                .join();
        System.out.println("CompletableFuture 变换结果：" + result);
    }

    /**
     * CompletableFuture 消费结果
     */
    public static void completableFutureTest02() {
        CompletableFuture.supplyAsync(() -> "Hello world")
                .thenAccept(v -> System.out.println("CompletableFuture 消费结果：" + v));
    }

    /**
     * CompletableFuture 结合两个 CompletionStage 的结果，进行转化后返回
     */
    public static void completableFutureTest03() {
        String result = CompletableFuture.supplyAsync(() -> {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return "Hello";
                }).thenCombine(CompletableFuture.supplyAsync(() -> {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return "world";
                }), (s1, s2) -> s1 + " " + s2)
                .join();
        System.out.println("CompletableFuture 结合两个 CompletionStage 的结果，进行转化后返回：" + result);
    }

    /**
     * 两个 CompletionStage 谁计算的快，就用那个 CompletionStage 的结果进行下一步的处理
     */
    public static void completableFutureTest04() {
        String result = CompletableFuture.supplyAsync(() -> {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return "Hi Boy";
                }).applyToEither(CompletableFuture.supplyAsync(() -> {
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return "Hi Girl";
                }), (s) -> s)
                .join();
        System.out.println("两个 CompletionStage 谁计算的快，就用那个 CompletionStage 的结果进行下一步的处理：" + result);
    }

    /**
     * 运行时出现了异常可以通过 exceptionally() 进行补偿
     */
    public static void completableFutureTest05() {
        String result = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (true) {
                throw new RuntimeException("exception test!");
            }
            return "Hi Boy";
        }).exceptionally(e -> {
            System.out.println(e.getMessage());
            return "Hello world!";
        }).join();
        System.out.println(result);
    }

    public static void completableFutureTest06() throws ExecutionException, InterruptedException {
        CompletableFuture<String> completableFuture = new CompletableFuture<>();
        new Thread(() -> {
            System.out.println("CompletableFuture 可以监控这个任务的执行");
            completableFuture.complete("任务返回结果");
        }).start();
        System.out.println(completableFuture.get());
    }

    public static void completableFutureTest07() throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.submit(() -> {
            System.out.println("executorService 是否为守护线程：" + Thread.currentThread().isDaemon());
            return null;
        });

        final CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("【forkJoinPool】开始");
            System.out.println("【forkJoinPool】supplyAsync 是否为守护线程：" + Thread.currentThread().isDaemon());
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("【forkJoinPool】结束");
            return "Result：forkJoinPool";
        });

        final CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("【ExecutorService】自定义开始");
            System.out.println("【ExecutorService】supplyAsync 是否为守护线程：" + Thread.currentThread().isDaemon());
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("【ExecutorService】自定义结束");
            return "Result：ExecutorService";
        }, executorService);

        System.out.println(completableFuture1.get());
        System.out.println(completableFuture2.get());
        executorService.shutdown();
    }
}
